package com.github.glomadrian.roadrunner.painter.determinate;

import com.github.glomadrian.roadrunner.painter.RoadRunnerPainter;
import com.github.glomadrian.roadrunner.painter.configuration.Direction;
import com.github.glomadrian.roadrunner.painter.configuration.determinate.TwoWayDeterminateConfiguration;
import com.github.glomadrian.roadrunner.painter.indeterminate.IndeterminatePathPainter;
import com.github.glomadrian.roadrunner.path.PathContainer;
import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.Component;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;

/**
 * @author Adrián García Lomas
 */
public class TwoWayDeterminatePainter extends RoadRunnerPainter
    implements DeterminatePathPainter, IndeterminatePathPainter {

  private AnimatorValue movementAnimator;
  private int movementLoopTime = 3000;
  private float movementLineSize = 0.03f;
  private float sideIncrementSize = 0f;

  /**
   * TwoWayDeterminatePainter
   *
   * @param pathData
   * @param view
   * @param twoWayDeterminateConfiguration
   */
  public TwoWayDeterminatePainter(PathContainer pathData, Component view,
      TwoWayDeterminateConfiguration twoWayDeterminateConfiguration) {
    super(pathData, view);
    initConfiguration(twoWayDeterminateConfiguration);
    init();
  }

  private void initConfiguration(TwoWayDeterminateConfiguration twoWayDeterminateConfiguration) {
    movementDirection = twoWayDeterminateConfiguration.getMovementDirection();
    color = twoWayDeterminateConfiguration.getColor();
    strokeWidth = twoWayDeterminateConfiguration.getStrokeWidth();
    movementLinePoints =
        getNumberOfLinePointsInRange(twoWayDeterminateConfiguration.getMovementLineSize());
    movementLoopTime = twoWayDeterminateConfiguration.getMovementLoopTime();
  }

  private void init() {
    initPaint();
    initLineMovement();
    initMovementAnimator();
  }

  /**
   * initPaint
   */
  public void initPaint() {
    paint = new Paint();
    paint.setColor(new Color(color));
    paint.setStrokeWidth(strokeWidth);
  }

  private void initLineMovement() {
    movementLinePoints = getNumberOfLinePointsInRange(movementLineSize);
  }

  private void initMovementAnimator() {
    movementAnimator = new AnimatorValue();
    movementAnimator.setDuration(movementLoopTime);
    movementAnimator.setCurveType(Animator.CurveType.LINEAR);
    movementAnimator.setLoopedCount(AnimatorValue.INFINITE);
    movementAnimator.setValueUpdateListener(new MovementLineAnimatorUpdateListener());
  }

  @Override
  public void paintPath(Canvas canvas) {
    int pointInRange = getNumberOfPointsInRange(sideIncrementSize) / 2;
    System.out.println("------ pointInRange = " + pointInRange);
    drawWithOffset(zone, pointInRange, pointInRange, movementLinePoints, canvas, paint);
  }

  @Override
  public void setProgress(float value) {
    if (value < 1F && value > 0) {
      sideIncrementSize = value;
      System.out.println("------ sideIncrementSize = " + sideIncrementSize);
      view.invalidate();
    }
  }

  @Override
  public void start() {
    movementAnimator.start();
  }

  @Override
  public void stop() {
    movementAnimator.end();
  }

  @Override
  public void restart() {
    movementAnimator.end();
    movementAnimator.start();
  }

  private class MovementLineAnimatorUpdateListener implements AnimatorValue.ValueUpdateListener {
    @Override
    public void onUpdate(AnimatorValue animatorValue, float v) {
      if (movementDirection.equals(Direction.CLOCKWISE)) {
        zone = v;
      } else {
        zone = 1 - v;
      }
      view.invalidate();
    }
  }
}
